package view;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.io.File;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import javax.swing.BorderFactory;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.border.TitledBorder;
import model.Acknowledgement;
import model.Email;
import model.Filter;
import model.EmailImp;
import model.MeetingInfo;
import model.MeetingMail;
import model.Template;
import resources.ResourceProvider;

/**
 * Mail display area will be represented by a JPanel having mail-table.
 *
 */
public class MailDisplayArea extends JPanel implements Observer
{
  
  private static final long serialVersionUID = -2230976657016812393L;
  
  private EmailApplicationView emailApplicationView;
  
  private MailTable table;
  private MeetingDetailsTable meetingTable;
  private MessagePanel messagePanel;
  private MeetingPanel meetingPanel;
  private SearchPanel searchPanel;
  private TemplatePanel templatePanel;
  private FilterPanel filterPanel;
  private FilterSettingPanel filterSettingPanel;
  private MeetingDetailDisplayPanel meetingDetailsdisplayPanel;
  private JScrollPane spane;
  
    /**
     *Mail display Area constructor will have emailApplicationView view
     *@param emailApplicationView the email application view reference
     */
  public MailDisplayArea(EmailApplicationView emailApplicationView)
   {
      TitledBorder title = BorderFactory.createTitledBorder(BorderFactory.createLineBorder(Color.black), "");
      this.setBorder(title);
      this.setLayout(new FlowLayout());   
      this.emailApplicationView = emailApplicationView;
   }

    /**
     * update call back with given action on UI
     * @param action the action of the update received in the Callback
     */
    public void update(String action)
    {
        if(ResourceProvider.NEW_MESSAGE.equals(action))
        {
            this.displayMessagePanel();
        }
        else if(ResourceProvider.NEW_MEETING.equals(action))
        {
            this.displayMeetingPanel();
        }
        else if(ResourceProvider.SEARCH.equals(action))
        {
            this.displaySearchPanel();
        }
        else if(ResourceProvider.REPLY_OPTION.equals(action))
        {
            if(messagePanel != null)
            {         
                Email email = MailDisplayArea.this.messagePanel.getEmail();
                // append data for reply email
                email.updateSubject("RE : " + email.getSubject());
                StringBuilder sbuilder = new StringBuilder();
                sbuilder.append("\n\n\n");
                sbuilder.append("_____________________" + "\n");
                sbuilder.append("From : " + email.getSender() + "\n");
                
                
                StringBuilder receivers = new StringBuilder("");
                List<String> receiversList = email.getReceiver();
                
                for(int n=0; n < receiversList.size(); n++ )
                {
                    receivers.append(receiversList.get(n));
                    if(n != (receiversList.size() - 1))
                    {
                        receivers.append(",");
                    }
                }
                
                sbuilder.append("To : " + receivers.toString() + "\n\n");
                sbuilder.append(email.getMessage() + "\n");
                
                email.updateMessage(sbuilder.toString());
                
                this.displaySelectedEmail(email,true);
            }
        }
        else if(ResourceProvider.ACCEPT.equals(action))
        {
            if(meetingPanel != null)
            {
                MeetingMail email = MailDisplayArea.this.meetingPanel.getEmail();
                String user = MailDisplayArea.this.emailApplicationView.getController().getUser();    
                List<String> receiver = new LinkedList<String>();
                receiver.add(email.getSender());
                
                DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
                Date date = new Date();
                String dateF = dateFormat.format(date); 
                
                Email ackEmail = new Email.Builder()
                .setSender(user)
                .setReceiver(receiver)
                .setSubject("Accepted :" + email.getSubject())
                .setMessage(email.getMessage())
                .setTimeOfCreation(dateF)
                .build();
                
                
                final String outBoxFolderPath = ResourceProvider.getRootFolderPath(ResourceProvider.OUTBOX,user);
                
                // persist email
                this.emailApplicationView.getController().requestPersitEmail(ackEmail,outBoxFolderPath);
              
                Acknowledgement ack = new Acknowledgement(Acknowledgement.ACK_MEETING_ACCEPTED,email.getMeetingId(),user);
                this.emailApplicationView.getController().getNetworkHandler().sendDataToClient(ResourceProvider.SERVER, ack,ResourceProvider.MAIN_SERVER_PORT);
                
                // update view/display area
                MailDisplayArea.this.displayEmails(ResourceProvider.getRootFolderPath(ResourceProvider.INBOX,user));
                MailDisplayArea.this.emailApplicationView.getButtonDisplayArea().displayButtons(ResourceProvider.getRootFolderPath(ResourceProvider.INBOX, user));

           }
        }
        else if(ResourceProvider.EDIT.equals(action))
        {
            if(meetingPanel != null)
            {
                MeetingMail email = MailDisplayArea.this.meetingPanel.getEmail();
                String meetingId = email.getMeetingId();
                String user = MailDisplayArea.this.emailApplicationView.getController().getUser();    
                String meetingPath = ResourceProvider.getRootFolderPath(ResourceProvider.MEETING, user);
                List<MeetingInfo> meetings = MailDisplayArea.this.emailApplicationView.getController().requestAllMeetingInfo(meetingPath);
                for(MeetingInfo meetInfo : meetings)
                {
                    if(meetInfo.meetingID.equals(meetingId))
                    {
                        this.displaySelectedMeetingDetail(meetInfo);
                        break;                
                    }
                 }
            }
            
        }
        else if(ResourceProvider.REJECT.equals(action))
        {
            if(meetingPanel != null)
            {
                MeetingMail email = MailDisplayArea.this.meetingPanel.getEmail();
                String user = MailDisplayArea.this.emailApplicationView.getController().getUser();    
                List<String> receiver = new LinkedList<String>();
                receiver.add(email.getSender());
                
                DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
                Date date = new Date();
                String dateF = dateFormat.format(date); 
                
                Email ackEmail = new Email.Builder()
                .setSender(user)
                .setReceiver(receiver)
                .setSubject("Rejected :" + email.getSubject())
                .setMessage(email.getMessage())
                .setTimeOfCreation(dateF)
                .build();
                
                
                final String outBoxFolderPath = ResourceProvider.getRootFolderPath(ResourceProvider.OUTBOX,user);
                
                // persist email
                this.emailApplicationView.getController().requestPersitEmail(ackEmail,outBoxFolderPath);
                
                Acknowledgement ack = new Acknowledgement(Acknowledgement.ACK_MEETING_REJECTED,email.getMeetingId(),user);
                this.emailApplicationView.getController().getNetworkHandler().sendDataToClient(ResourceProvider.SERVER, ack,ResourceProvider.MAIN_SERVER_PORT);
                
                // update view/display area
                MailDisplayArea.this.displayEmails(ResourceProvider.getRootFolderPath(ResourceProvider.INBOX,user));
                MailDisplayArea.this.emailApplicationView.getButtonDisplayArea().displayButtons(ResourceProvider.getRootFolderPath(ResourceProvider.INBOX, user));

           }
        }
        else if(ResourceProvider.DELETE_MEETING.equals(action))
        {
            if(meetingDetailsdisplayPanel != null)
            {
                MeetingInfo meetingInfo = meetingDetailsdisplayPanel.getMeetingInfo();
                String user = MailDisplayArea.this.emailApplicationView.getController().getUser();    
               
                
                DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
                Date date = new Date();
                String dateF = dateFormat.format(date); 
                
                Email ackEmail = new Email.Builder()
                .setSender(user)
                .setReceiver(meetingInfo.receivers)
                .setSubject("Cancelled :" + meetingInfo.originalSubject)
                .setMessage(meetingInfo.originalMessage)
                .setTimeOfCreation(dateF)
                .build();
                
                
                final String outBoxFolderPath = ResourceProvider.getRootFolderPath(ResourceProvider.OUTBOX,user);
                
                // persist email
                this.emailApplicationView.getController().requestPersitEmail(ackEmail,outBoxFolderPath);
                
                Acknowledgement ack = new Acknowledgement(Acknowledgement.ACK_MEETING_CANCELLED,meetingInfo.meetingID,user);
                this.emailApplicationView.getController().getNetworkHandler().sendDataToClient(ResourceProvider.SERVER, ack,ResourceProvider.MAIN_SERVER_PORT);
                
                // update view/display area
                MailDisplayArea.this.displayEmails(ResourceProvider.getRootFolderPath(ResourceProvider.INBOX,user));
                MailDisplayArea.this.emailApplicationView.getButtonDisplayArea().displayButtons(ResourceProvider.getRootFolderPath(ResourceProvider.INBOX, user));
           }
        }
        else if(ResourceProvider.DELETE_OPTION.equals(action))
        {
           if(templatePanel != null)
           {
               String user = MailDisplayArea.this.emailApplicationView.getController().getUser();    
               String templateFolderPath = ResourceProvider.getRootFolderPath(ResourceProvider.TEMPLATES, user);
              
               Template template = templatePanel.getTemplate();
               MailDisplayArea.this.emailApplicationView.getController().requestFileDelete(templateFolderPath + ResourceProvider.getFilePathSeperator() + template.getFileName() + ".json");
               
               this.reset();
               MailDisplayArea.this.emailApplicationView.getButtonDisplayArea().displayButtonsForTemplates();
           }
           else if(filterPanel != null)
           {
               String user = MailDisplayArea.this.emailApplicationView.getController().getUser();    
               String filterFolderPath = ResourceProvider.getRootFolderPath(ResourceProvider.FILTERS, user);
              
               Filter filter = filterPanel.getFilter();
               MailDisplayArea.this.emailApplicationView.getController().requestFileDelete(filterFolderPath + ResourceProvider.getFilePathSeperator() + filter.getFileName() + ".json");
               
               this.reset();
               MailDisplayArea.this.emailApplicationView.getButtonDisplayArea().displayButtonsForFilters();
           }
           else
           {
               List<EmailImp> listOfEmails = this.getSelectedEmails();
               for(EmailImp email : listOfEmails)
               {    
                   String user = MailDisplayArea.this.emailApplicationView.getController().getUser();    
                   String thrashFolderPath = ResourceProvider.getRootFolderPath(ResourceProvider.TRASH, user);
                   
                   String filePath = email.getPersistencePath();
                   if(filePath.contains(thrashFolderPath))
                   {
                       // delete the email(s) permanently
                       MailDisplayArea.this.emailApplicationView.getController().requestFileDelete(filePath);
                   }
                   else
                   {
                       // move the email(s) to Thrash 
                       String destinationFilePath = thrashFolderPath;
                       MailDisplayArea.this.emailApplicationView.getController().requestFileDelete(filePath);
                       MailDisplayArea.this.emailApplicationView.getController().requestPersitEmail(email, destinationFilePath);
                   }
                   
    
                   String path = MailDisplayArea.this.emailApplicationView.getFoldHierarchyPanel().getSelectedTreeNodePath();
                   MailDisplayArea.this.displayEmails(path); 
               }
           }
        }
        else if(ResourceProvider.MY_MEETING.equals(action))
        {
            String user = this.emailApplicationView.getController().getUser();
            List<MeetingInfo> allMeetingInfo =  MailDisplayArea.this.emailApplicationView.getController().requestAllMeetingInfo(ResourceProvider.getRootFolderPath(ResourceProvider.MEETING,user));
            this.displayMeetingInfo(allMeetingInfo);
        }
        else if(ResourceProvider.UPDATE_MEETING.equals(action))
        {
            if(meetingDetailsdisplayPanel != null)
            {
                MeetingInfo meetingInfo = meetingDetailsdisplayPanel.getMeetingInfo();
                String newMessage = meetingDetailsdisplayPanel.getMessage();
                String newSubject = meetingDetailsdisplayPanel.getSubject();
                String newLocation = meetingDetailsdisplayPanel.getPlace();
                String newStartTime = meetingDetailsdisplayPanel.getStartTime();
                String newEndTime = meetingDetailsdisplayPanel.getEndTime();

                String user = this.emailApplicationView.getController().getUser();
                
                Map<Integer,String> changes = new LinkedHashMap<Integer,String>();
                
                changes.put(MeetingInfo.MEETING_ID, meetingInfo.meetingID);
                changes.put(MeetingInfo.USER, user);

                
                if(!meetingInfo.originalMessage.equalsIgnoreCase(newMessage))
                {
                    changes.put(MeetingInfo.MEETING_MESSAGE_CHANGED, newMessage);
                }
                
                if(!meetingInfo.originalSubject.equalsIgnoreCase(newSubject))
                {
                    changes.put(MeetingInfo.MEETING_SUBJECT_CHANGED, newSubject);
                }
                
                if(!meetingInfo.originalStartTime.equalsIgnoreCase(newStartTime))
                {
                    changes.put(MeetingInfo.MEETING_START_TIME_CHANGED, newStartTime);
                }
                
                if(!meetingInfo.originalEndiTime.equalsIgnoreCase(newEndTime))
                {
                    changes.put(MeetingInfo.MEETING_END_TIME_CHANGED, newEndTime);
                }
                
                if(!meetingInfo.origianlPlace.equalsIgnoreCase(newLocation))
                {
                    changes.put(MeetingInfo.MEETING_LOCATION_CHANGED, newLocation);
                }
                
                Acknowledgement ack = new Acknowledgement(Acknowledgement.ACK_MEETING_ACCEPTED,meetingInfo.meetingID,user);
                this.emailApplicationView.getController().getNetworkHandler().sendDataToClient(ResourceProvider.SERVER, ack,ResourceProvider.MAIN_SERVER_PORT);
                
                Acknowledgement ack1 = new Acknowledgement(Acknowledgement.ACK_MEETING_UPDATED_By_USER, changes,user);
                this.emailApplicationView.getController().getNetworkHandler().sendDataToClient(ResourceProvider.SERVER, ack1,ResourceProvider.MAIN_SERVER_PORT);
                
                // update view/display area
                MailDisplayArea.this.displayEmails(ResourceProvider.getRootFolderPath(ResourceProvider.INBOX,user));
                MailDisplayArea.this.emailApplicationView.getButtonDisplayArea().displayButtons(ResourceProvider.getRootFolderPath(ResourceProvider.INBOX, user));


            }
        }
        else if(ResourceProvider.MOVE_TO.equals(action))
        {   
           EmailFolderNode optionInbox = new EmailFolderNode(ResourceProvider.INBOX);
           String user = this.emailApplicationView.getController().getUser();
           optionInbox.setPersistenceFilePath(ResourceProvider.getRootFolderPath(ResourceProvider.INBOX, user));
           JTree tree = new JTree(optionInbox); 
           MailDisplayArea.this.loadPersistenceFolders(optionInbox);
           JPanel panel = new JPanel();
           panel.setLayout(new BorderLayout(10, 10));
           TitledBorder title = BorderFactory.createTitledBorder(BorderFactory.createLineBorder(Color.black), "");
           panel.setBorder(title);
           panel.add(new JScrollPane(tree));
           for (int j = 0; j < tree.getRowCount(); j++) 
           {
               tree.expandRow(j);
           }
                      
           int optionSelected = JOptionPane.showConfirmDialog(null,
                panel,
                "Move To",
                JOptionPane.OK_CANCEL_OPTION,
                JOptionPane.PLAIN_MESSAGE);
           
           if(optionSelected == JOptionPane.OK_OPTION)
           {
               EmailFolderNode selectedNode = (EmailFolderNode) tree.getLastSelectedPathComponent();
               String destinationPathToMove = selectedNode.getPersistenceFilePath();
               List<EmailImp> selectedListOFEmailToMove = this.getSelectedEmails();
               String seperator = ResourceProvider.getFilePathSeperator();
               
               if(!destinationPathToMove.equals("") && (selectedListOFEmailToMove.size() > 0))
               {                                   
                   EmailImp firstEmail = selectedListOFEmailToMove.get(0);
                   String seperatorForSplit = "";
                   if(ResourceProvider.isMac())
                   {
                       seperatorForSplit = "/";
                   }
                   else
                   {
                       seperatorForSplit = "\\\\";
                   }
                   
                   String[] split = firstEmail.getPersistencePath().split(seperatorForSplit);
                   
                   String fileName = split[split.length-1];
                   StringBuilder sourceFolderPath = new StringBuilder();
                   for(int n =0;n<split.length-1;n++)
                   {
                       sourceFolderPath.append(split[n]).append(seperator);
                   }
 
                   for(EmailImp email : selectedListOFEmailToMove)
                   {
                     //persist folder
                     MailDisplayArea.this.emailApplicationView.getController().requestMoveToFile(email.getPersistencePath(), destinationPathToMove+ seperator + fileName);
                   }
                   
                   // update view/display area
                   MailDisplayArea.this.displayEmails(sourceFolderPath.toString()); 
               }
           } 
        }
        else if(ResourceProvider.SEND_OPTION.equals(action))
        {
            if(messagePanel != null)
            {
                final Email newMail = messagePanel.getEmail();
                List<String> list = messagePanel.getEmail().getReceiver();
                
                if((list.size() == 1) && (list.get(0).equalsIgnoreCase("")))
                {
                    
                    final JPanel panel = new JPanel();
                  JOptionPane.showMessageDialog(panel, "To field cannot be left blank", "Warning",
                  JOptionPane.WARNING_MESSAGE);   
                    return;
                }               
                if((newMail.getSubject().equals("")))
                {

                      final JPanel panel = new JPanel();
                      JOptionPane.showMessageDialog(panel, "Subject field cannot be left blank", "Warning",
                      JOptionPane.WARNING_MESSAGE);   
                      return;
                }                    
                if((newMail.getMessage().equals("")))
                {
                    final JPanel panel = new JPanel();
                    JOptionPane.showMessageDialog(panel, "Message field cannot be left blank", "Warning",
                    JOptionPane.WARNING_MESSAGE);   
                    return;
                }
                if(!validateEmailId(newMail.getReceiver()))
                {
                    final JPanel panel = new JPanel();
                    JOptionPane.showMessageDialog(panel, "To address is invalid!", "Warning",
                    JOptionPane.WARNING_MESSAGE);   
                    return;         
                }
                
                //delete file if old exist                
                boolean doesFileExistAndDeleted = this.emailApplicationView.getController().requestFileDelete(newMail.getPersistencePath());
                if(doesFileExistAndDeleted)
                {
                    DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
                    Date date = new Date();
                    String dateF = dateFormat.format(date);
                    newMail.updateTime(dateF);  
                }     
                
                final String user = this.emailApplicationView.getController().getUser();
                final String outBoxFolderPath = ResourceProvider.getRootFolderPath(ResourceProvider.OUTBOX,user);
                
                // persist email
                this.emailApplicationView.getController().requestPersitEmail(newMail,outBoxFolderPath);
                
                // update view/display area
                MailDisplayArea.this.displayEmails(ResourceProvider.getRootFolderPath(ResourceProvider.INBOX,user));
                MailDisplayArea.this.emailApplicationView.getButtonDisplayArea().displayButtons(ResourceProvider.getRootFolderPath(ResourceProvider.INBOX, user));
                
            }
            else if(meetingPanel != null)
            {
                 final MeetingMail newMail = meetingPanel.getEmail();
                 List<String> list = meetingPanel.getEmail().getReceiver();
                 
                 if((list.size() == 1) && (list.get(0).equalsIgnoreCase("")))
                 {
                     
                     final JPanel panel = new JPanel();
                   JOptionPane.showMessageDialog(panel, "To field cannot be left blank", "Warning",
                   JOptionPane.WARNING_MESSAGE);   
                     return;
                 }               
                 if((newMail.getSubject().equals("")))
                 {

                       final JPanel panel = new JPanel();
                       JOptionPane.showMessageDialog(panel, "Subject field cannot be left blank", "Warning",
                       JOptionPane.WARNING_MESSAGE);   
                       return;
                 }                    
                 if((newMail.getMessage().equals("")))
                 {
                     final JPanel panel = new JPanel();
                     JOptionPane.showMessageDialog(panel, "Message field cannot be left blank", "Warning",
                     JOptionPane.WARNING_MESSAGE);   
                     return;
                 }
                 if(!validateEmailId(newMail.getReceiver()))
                 {
                     final JPanel panel = new JPanel();
                     JOptionPane.showMessageDialog(panel, "To address is invalid!", "Warning",
                     JOptionPane.WARNING_MESSAGE);   
                     return;         
                 }
                 
                 //delete file if old exist                
                 boolean doesFileExistAndDeleted = this.emailApplicationView.getController().requestFileDelete(newMail.getPersistencePath());
                 if(doesFileExistAndDeleted)
                 {
                     DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
                     Date date = new Date();
                     String dateF = dateFormat.format(date);
                     newMail.updateTime(dateF);  
                 }     
                 
                 final String user = this.emailApplicationView.getController().getUser();
                 final String outBoxFolderPath = ResourceProvider.getRootFolderPath(ResourceProvider.OUTBOX,user);
                 
                 // persist email
                 this.emailApplicationView.getController().requestPersitEmail(newMail,outBoxFolderPath);
                 
                 String meetingID = newMail.getMeetingId();
                 String meetingPath = ResourceProvider.getRootFolderPath(ResourceProvider.MEETING, user);
                 String meetingDataPath = meetingPath + ResourceProvider.getFilePathSeperator() + meetingID + ".json";
                 //check if meetingID is already have meeting info
                 if(!new File(meetingDataPath).exists())
                 {
                     //creating for the first time
                     MeetingInfo info = new MeetingInfo(meetingID);
                     info.setOrigianlPlace(newMail.getMeetingPlace());
                     info.setOriginalMessage(newMail.getMessage());
                     info.setOriginalStartTime(newMail.getStartTime());
                     info.setOriginalEndiTime(newMail.getEndTime());
                     info.setOriginalSubject(newMail.getSubject());
                     info.setReceivers(newMail.getReceiver());
                     info.setSender(newMail.getSender());
                     MailDisplayArea.this.emailApplicationView.getController().requestPersistMeetingInfo(info, meetingPath);
                 } 
                 
                 
                 // update view/display area
                 MailDisplayArea.this.displayEmails(ResourceProvider.getRootFolderPath(ResourceProvider.INBOX,user));
                 MailDisplayArea.this.emailApplicationView.getButtonDisplayArea().displayButtons(ResourceProvider.getRootFolderPath(ResourceProvider.INBOX, user));
               
            }
        }
        else if(ResourceProvider.SAVE_TO_DRAFT_OPTION.equals(action))
        {
            if(messagePanel != null)
            {
                Email newMail = messagePanel.getEmail();
                
                String user = this.emailApplicationView.getController().getUser();
                String draftFolderPath = ResourceProvider.getRootFolderPath(ResourceProvider.DRAFT, user);
                
                this.emailApplicationView.getController().requestPersitEmail(newMail,draftFolderPath);
                
                // update view/display area
                MailDisplayArea.this.displayEmails(ResourceProvider.getRootFolderPath(ResourceProvider.INBOX,user));
                MailDisplayArea.this.emailApplicationView.getButtonDisplayArea().displayButtons(ResourceProvider.getRootFolderPath(ResourceProvider.INBOX, user));
            }
        }
        else if(ResourceProvider.CANCEL_OPTION.equals(action))
        {
            if(templatePanel != null)
            {        
                MailDisplayArea.this.emailApplicationView.getButtonDisplayArea().displayButtonsForTemplates();
                this.reset();
            }
            else if(filterPanel != null)
            {        
                MailDisplayArea.this.emailApplicationView.getButtonDisplayArea().displayButtonsForFilters();
                this.reset();
            }
            else
            {
                String user  = MailDisplayArea.this.emailApplicationView.getController().getUser();
                
                // update view/display area
                MailDisplayArea.this.displayEmails(ResourceProvider.getRootFolderPath(ResourceProvider.INBOX,user));
                MailDisplayArea.this.emailApplicationView.getButtonDisplayArea().displayButtons(ResourceProvider.getRootFolderPath(ResourceProvider.INBOX, user));
            }
        }
        else if(ResourceProvider.LOAD_OPTION.equals(action))
        {
          if(templatePanel != null)
          {
              MailDisplayArea.this.emailApplicationView.getButtonDisplayArea().displayButtonsToEditOrDelete();
          }
        }
        else if(ResourceProvider.TEMPLATES.equals(action))
        {           
            MailDisplayArea.this.reset();
        }
        else if(ResourceProvider.CREATETEM_OPTION.equals(action))
        {
            this.displayTemplatePanel();
        }
        else if(ResourceProvider.CREATE_FILTER_OPTION.equals(action))
        {
            this.displayFilterPanel();
        }
        else if(ResourceProvider.FILTER_SETTING.equals(action))
        {
            this.displayFilterSettingPanel();
        }
        else if(ResourceProvider.SAVE_OPTION.equals(action))
        {
             if(templatePanel != null)
             {               
                 String newTemplateName = emailApplicationView.getMailDisplayArea().templatePanel.getTemplate().getTemplateName(); 
                 if((emailApplicationView.getMailDisplayArea().templatePanel.getTemplate().getTemplateName().equals("")))
                 {
                    final JPanel panel = new JPanel();
                    JOptionPane.showMessageDialog(panel, "Name field cannot be left blank", "Warning",
                    JOptionPane.WARNING_MESSAGE);   
                    this.emailApplicationView.getButtonDisplayArea().displayButtonsForCreateTemplate();
                    //return;
                 }
                 else if(newTemplateName.matches(".*?[\\p{Punct}&&[^_]].*"))
                 {
                    final JPanel panel = new JPanel();
                    JOptionPane.showMessageDialog(panel, "Name cannot contain special characters", "Warning",
                    JOptionPane.WARNING_MESSAGE);
                 }           
                 else if(isTemplateExist(newTemplateName))
                 {          
                    JOptionPane.showMessageDialog(this.getParent().getParent().getParent().getParent(), "Sorry, template name already exists!", "Warning",
                    JOptionPane.WARNING_MESSAGE);                   
                 }
                 else
                 {
                     String user = this.emailApplicationView.getController().getUser();
                     String templatesFolderPath = ResourceProvider.getRootFolderPath(ResourceProvider.TEMPLATES, user);  
                     Template template = templatePanel.getTemplate();
                     MailDisplayArea.this.emailApplicationView.getButtonDisplayArea().displayButtonsForTemplates();
                     this.emailApplicationView.getController().requestPersistTemplate(template, templatesFolderPath);               
                     this.reset();
                     
                     this.emailApplicationView.getButtonDisplayArea().displayButtonsForTemplates();
                 }
             }
             else if(filterPanel != null)
             {
                 String user = this.emailApplicationView.getController().getUser();
                 String filtersFolderPath = ResourceProvider.getRootFolderPath(ResourceProvider.FILTERS, user);  
                 Filter filter = filterPanel.getFilter();
                 MailDisplayArea.this.emailApplicationView.getButtonDisplayArea().displayButtonsForFilters();
                 this.emailApplicationView.getController().requestPersistFilter(filter, filtersFolderPath);               
                 this.reset();
                 
                 this.emailApplicationView.getButtonDisplayArea().displayButtonsForFilters();
             }
          }
        }

    /**
     * display meeting information in MeetingDetailsTable
     * @param List<MeetingInfo> allMeetingInfo the list which has the meeting information
     */
    private void displayMeetingInfo(List<MeetingInfo> allMeetingInfo)
    {
      this.reset();
      
      MeetingModel model = new MeetingModel(allMeetingInfo);
      this.meetingTable = new MeetingDetailsTable(this,model);
      
      this.add(new JScrollPane(this.meetingTable),BorderLayout.CENTER);
    
      this.revalidate();
      this.repaint();        
    }

    /**
     * display filter setting panel
     */
    public void displayFilterSettingPanel()
    {
        this.reset();
        
        filterSettingPanel = new FilterSettingPanel(this);
        spane = new JScrollPane(filterSettingPanel);
        this.add(spane);
        
        filterSettingPanel.loadPriorityPanels();

        this.revalidate();
        this.repaint();  
    }

    /**
     * display filter panel
     */
    public void displayFilterPanel()
    {
        this.reset();
        filterPanel = new FilterPanel(this);
        this.add(filterPanel);

        this.revalidate();
        this.repaint();             
    }

    /**
     * does new template name already exist
     * @param newTemplateName  the name of the new template as string 
     * @return true if the name already exist else false
     */
    public boolean isTemplateExist(String newTemplateName) 
    {
        String user = this.emailApplicationView.getController().getUser();
        String path = ResourceProvider.getRootFolderPath(ResourceProvider.TEMPLATES, user);
        File directory = new File( path );
        for( File file : directory.listFiles() )
        {
           if( file.getName().equals( newTemplateName + ".json") )
           {
             return true;
           }
        } 
        return false;
    }

    /**
     * display Template panel
     */
    public void displayTemplatePanel()
    {
        this.reset();
        templatePanel = new TemplatePanel();
        this.add(templatePanel);

        this.revalidate();
        this.repaint();          
    }

    /**
     * display search panel
     */
    public void displaySearchPanel()
    {
        this.reset();
        searchPanel = new SearchPanel(this);
        this.add(searchPanel);

        this.revalidate();
        this.repaint();        
    }

    /**
     * validate email id format
     * @param list of email id(s)
     * @return return true if the email is valid else false
     */
    public boolean validateEmailId(List<String> list)
    {
        for(String emailID: list )
        {
            String EMAIL_REGEX = "^[\\w-_\\.+]*[\\w-_\\.]\\@([\\w]+\\.)+[\\w]+[\\w]$";
            if(!emailID.matches(EMAIL_REGEX))
            {
                return false;
            }
        }
        
        return true;    
    }

    /**
     * display message panel for email
     */
    public void displayMessagePanel() 
    {
        this.reset();
        messagePanel = new MessagePanel(this);
        this.add(messagePanel);

        this.revalidate();
        this.repaint();
    }
    
     /**
     * display meeting panel for email
     */
    public void displayMeetingPanel() 
    {
        this.reset();
        meetingPanel = new MeetingPanel(this);
        this.add(meetingPanel);

        this.revalidate();
        this.repaint();
    }
    
    /**
     * display templates list after clicking template button
     * @param templatePath path to the template
     */
    public void displayTemplateList(String templatePath)
    {
        this.reset();
        
        List<EmailImp> mails = this.loadEmails(templatePath);
        
        EmailTableModel model = new EmailTableModel(templatePath, mails);
        this.table = new MailTable(this,model);
        
        this.add(new JScrollPane(table),BorderLayout.CENTER);
        
        this.revalidate();
        this.repaint();
    }

    /**
     * display emails in the view for the give folder path
     * @param path path to the emails.
     */
    public void displayEmails(String path)
    {        
        this.reset();
        
        List<EmailImp> mails = this.loadEmails(path);
        
        EmailTableModel model = new EmailTableModel(path, mails);
        this.table = new MailTable(this,model);
        
        this.add(new JScrollPane(table),BorderLayout.CENTER);
        
      
        this.revalidate();
        this.repaint();
    }
    
    /**
     * display email(s) in the view for the give folder path
     * @param emails the list of email to display
     */
    public void displayEmails(List<EmailImp> emails)
    {        
        this.reset();
        
        
        EmailTableModel model = new EmailTableModel(ResourceProvider.INBOX, emails);
        this.table = new MailTable(this,model);
        
        this.add(new JScrollPane(table),BorderLayout.CENTER);
        
      
        this.revalidate();
        this.repaint();
    }

    /**
     * @param load the given path to load from
     * @return the list of email(s) in the given path
     */
    private List<EmailImp> loadEmails(String path)
    {
            List<EmailImp> emailList = new LinkedList<EmailImp>();
            String user = this.emailApplicationView.getController().getUser();

            if(path.equals(ResourceProvider.getRootFolderPath(ResourceProvider.INBOX, user)))
            {
                List<File> emailFiles = this.emailApplicationView.getController().requestEmailFilesFromFolder(path);
 
                for(File email : emailFiles)
                {
                    EmailImp eMailObj = this.emailApplicationView.getEmailFromJasonFile(email);
                    emailList.add(eMailObj);
                }       
            }
            else
            {
               List<File> emailFiles = this.emailApplicationView.getController().requestEmailFilesDeepInsideFolder(path);
               for(File email : emailFiles)
               {
                   EmailImp eMailObj = this.emailApplicationView.getEmailFromJasonFile(email);
                   emailList.add(eMailObj);
               } 
            }
        
            return emailList;
    }
    
    /**
     * get selected emails
     * @return list of selected email(s)
     */
    public List<EmailImp> getSelectedEmails()
    {
        if(this.table == null)
        {
            return new LinkedList<EmailImp>();
        }
        return ((EmailTableModel)this.table.getModel()).getSelectedMails();
    }
    
    /**
     * get email application view
     * @return get email application view reference
     */
    public EmailApplicationView getEmailApplicationView()
    {
        return emailApplicationView;
    }
    
    
    /**display Move To Option
     * @param optionInbox one can move emails from inbox to specified folders
     */
    public void loadPersistenceFolders(EmailFolderNode optionInbox)
    {
        String user = this.emailApplicationView.getController().getUser();
        String inboxFolder = ResourceProvider.getRootFolderPath(ResourceProvider.INBOX, user);
        
        File outBoxFolder = new File(inboxFolder);
        File[] listOfFiles = outBoxFolder.listFiles(); 
       
        for(File file : listOfFiles)
        {
             if (file.isDirectory() && !file.getName().endsWith(".svn")) 
             {
                 EmailFolderNode emailFolderNode = new EmailFolderNode(file.getName());
                 emailFolderNode.setPersistenceFilePath(file.getPath());
                 optionInbox.add(emailFolderNode);
                 this.iteratePersistenceFolders(file, emailFolderNode);
                 
             }
        }
    }
    
    /**
     * iterate through persistence folders
     * @param folder specified folder of the file
     * @param emailFolderNode emailfolder node 
     */
    private void iteratePersistenceFolders(File folder,EmailFolderNode emailFolderNode)
    {
        File[] listOfFiles = folder.listFiles(); 
        for(File file : listOfFiles)
        {
             if (file.isDirectory() && !file.getName().endsWith(".svn")) 
             {
                 EmailFolderNode newEmailFolderNode = new EmailFolderNode(file.getName());
                 newEmailFolderNode.setPersistenceFilePath(file.getPath());
                 emailFolderNode.add(newEmailFolderNode);
                 this.iteratePersistenceFolders(file,newEmailFolderNode);
             }
        }
    }

    /**
     * display selected email
     * @param email email selected by the user
     * @param reply reply by the reeciever for the specific meeting either accept or reject
     */
    public void displaySelectedEmail(EmailImp email, boolean reply)
    {
        this.reset();
        
        if(email instanceof MeetingMail)
        {
            meetingPanel = new MeetingPanel(this,email,reply);
            this.add(meetingPanel);
            this.emailApplicationView.getButtonDisplayArea().displayButtonsForMeetingEmail((MeetingMail)email);
        }
        else
        {
            messagePanel = new MessagePanel(this,email,reply);
            this.add(messagePanel);
        
            this.emailApplicationView.getButtonDisplayArea().displayButtonsForEmail(reply);
        }

        this.revalidate();
        this.repaint();        
    }
    
    /**
     * get email from the view panel
     */
    public Email getMail()
    {
         return  MailDisplayArea.this.messagePanel.getEmail();

    }

    /**
     * Display search results, given the two basic parameters.
     * @param textToSearch is the search query provided by the user.
     * @param isRegex regular expersion provided by the user 
     */
    public void displaySearchResuls(String textToSearch, boolean isRegEx)
    {
        List<EmailImp> emails = new LinkedList<EmailImp>();
        
        String user = this.emailApplicationView.getController().getUser(); 
        List<File> searchResultFiles = this.emailApplicationView.getController().requestSearchResult(user, textToSearch, isRegEx);
               
        for(File email : searchResultFiles)
        {
            EmailImp eMailObj = this.emailApplicationView.getEmailFromJasonFile(email);
            emails.add(eMailObj);
        }
        
        this.displayEmails(emails);
    }
    
    /**
     * Method to display search results based on specifically provided parameters.
     * @param subject the key words to search in the subject of the emails.
     * @param from the key words to search in the recipients of the emails.
     * @param words key words separated by commas to search in the message body of the emails.
     */
    public void displayAdvancedSearchResuls(String from, String subject, String words)
    {
        List<EmailImp> emails = new LinkedList<EmailImp>();
        String user = this.emailApplicationView.getController().getUser();
        Map<String,File> fromResultFiles = new HashMap<String,File>();
        Map<String,File> subjectResultFiles = new HashMap<String,File>();
        Map<String,File> wordsResultFiles = new HashMap<String,File>();
        
        if(!"".equals(from.trim()))
            fromResultFiles = this.emailApplicationView.getController().requestAdvancedSearchResult(user, from, ResourceProvider.SEARCH_EMAIL_FROM);
        if(!"".equals(words.trim()))
            subjectResultFiles = this.emailApplicationView.getController().requestAdvancedSearchResult(user, words, ResourceProvider.SEARCH_EMAIL_MESSAGE);
        if(!"".equals(subject.trim()))
            wordsResultFiles = this.emailApplicationView.getController().requestAdvancedSearchResult(user, subject, ResourceProvider.SEARCH_EMAIL_SUBJECT);
        
        List<File> searchResultFiles = this.emailApplicationView.getController().mergeAndConvertToList(fromResultFiles, subjectResultFiles, wordsResultFiles); 
        
        for(File email : searchResultFiles)
        {
            EmailImp eMailObj = this.emailApplicationView.getEmailFromJasonFile(email);
            emails.add(eMailObj);
        }
        
        this.displayEmails(emails); 
            
    }

    /**
     * load template and display template panel
     * @param tempL the temaplate
     */
    public void loadTemplate(Template tempL)
    {
       if(messagePanel != null)
       {
           this.messagePanel.loadTemplate(tempL); 
       }
       else if(meetingPanel != null)
       {
           this.meetingPanel.loadTemplate(tempL); 
       }
       else
       {
           this.displayTemplatePanel();
           this.templatePanel.loadTemplate(tempL);
       }
    }
    
    /**
     * load Filter and display Filter Panel 
     * @param filR the fiter
     */
    public void displayFilter(Filter filR)
    {
       if(filterPanel != null)
       {
           this.filterPanel.loadFilter(filR); 
       }
       else
       {
           this.displayFilterPanel();
           this.filterPanel.loadFilter(filR);
       }
    }
    
    /**
     * reset all the panels by assigning null
     */
    public void reset()
    {
        this.removeAll();
        
        this.table = null;
        this.meetingTable = null;
        this.messagePanel = null;
        this.meetingPanel = null;
        this.searchPanel = null;
        this.templatePanel = null;
        this.filterPanel = null;
        this.filterSettingPanel = null;
        this.meetingDetailsdisplayPanel = null;
        this.spane = null;
        
        this.revalidate();
        this.repaint(); 
    }
    /**
     * display selected meeting information
     * @param MeetingInfo meeting
     */
    
    public void displaySelectedMeetingDetail(MeetingInfo meeting)
    {
        String user = MailDisplayArea.this.emailApplicationView.getController().getUser();    
        Map<Integer, String> data  = meeting.meetingParticipantData;
        String  status = data.get(user.hashCode());
        
        
        if(status.equals(MeetingInfo.MEETING_CANCELLED))
        {    
            this.emailApplicationView.getButtonDisplayArea().displayNothing(true);           
        }
        else
        {
            this.emailApplicationView.getButtonDisplayArea().displayMeetingEditOptionButtons();            
        }
        
        
      this.reset();
      
      meetingDetailsdisplayPanel = new MeetingDetailDisplayPanel(this,meeting);
      spane = new JScrollPane(meetingDetailsdisplayPanel);
      this.add(spane);
      
      meetingDetailsdisplayPanel.loadRecepientsDetail();
      
      this.revalidate();
      this.repaint();
    }
    
}
